package net.worldscale.xp.wslib.urm;

import java.io.InputStream;

import net.worldscale.xp.wslib.urm.loader.ILoaderListener;
import net.worldscale.xp.wslib.urm.loader.Loader;

final class ImplResource extends Resource implements ILoaderListener {

	public ImplResource(String uri, Sandbox owner) {
		mOwner = owner;
		mOriginURI = uri;
	}

	private final Sandbox mOwner;
	private final String mOriginURI;
	private boolean mIsLoadingStarted = false;
	private boolean mIsLoading = false;
	private Loader mLoader;
	private Object mObject;

	@Override
	public Sandbox getOwnerSandbox() {
		return mOwner;
	}

	@Override
	public String getURI() {
		final Loader ldr = this.mLoader;
		if (ldr == null) {
			return this.mOriginURI;
		}
		return ldr.getURI();
	}

	@Override
	public String getFinalURI() {
		final Loader ldr = this.mLoader;
		if (ldr == null) {
			return this.mOriginURI;
		}
		return ldr.getFinalURI();
	}

	@Override
	public String getMimeType() {
		final Loader ldr = this.mLoader;
		if (ldr == null) {
			return "";
		}
		return ldr.getMimeType();
	}

	@Override
	public Object getObject() {
		return mObject;
	}

	@Override
	public String getOriginURI() {
		return this.mOriginURI;
	}

	@Override
	public void putObject(Object obj) {
		mObject = obj;
	}

	@Override
	public void cancel() {
		final Loader ldr = this.mLoader;
		if (ldr == null) {
			return;
		}
		ldr.cancel();
	}

	@Override
	public void load() {
		if (!mIsLoadingStarted) {
			doLoad();
		}
	}

	@Override
	public void reload() {
		if (!mIsLoading) {
			doLoad();
		}
	}

	private void doLoad() {
		mIsLoadingStarted = true;
		mIsLoading = true;
		final Loader ldr = Loader.newInstance(this.mOriginURI);
		ldr.setListener(this);
		if (this.mLoader == null) {
			this.mLoader = ldr;
		}
		ldr.loadAsync();
	}

	@Override
	public boolean onMimeType(Loader ldr, String mime) {
		return this.mOwner.getListener().onMimeType(this, mime);
	}

	@Override
	public InputStream openInputStream() {
		final Loader ldr = this.mLoader;
		if (ldr == null) {
			return null;
		}
		return ldr.openInputStream();
	}

	@Override
	public boolean isComplete() {
		final Loader ldr = this.mLoader;
		if (ldr == null) {
			return false;
		}
		return (ldr.getPhase() == Loader.PHASE_COMPLETE);
	}

	@Override
	public boolean isMain() {
		final Resource mainRes = this.mOwner.getMainResource();
		return this.equals(mainRes);
	}

	@Override
	public void onFinish(Loader ldr) {
		this.mIsLoading = false;
		this.mLoader = ldr;
		this.mOwner.getListener().onLoadingFinish(this);
	}

	@Override
	public long getLoadedLength() {
		final Loader ldr = this.mLoader;
		if (ldr == null)
			return 0;
		return ldr.getLoadedLength();
	}

	@Override
	public long getTotalLength() {
		final Loader ldr = this.mLoader;
		if (ldr == null)
			return 0;
		return ldr.getTotalLength();
	}

}
